package com.mjf.cjt.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mjf.cjt.domain.TCjtzjbSaleDelivery;
import com.mjf.cjt.domain.TCjtzjbSaleDeliveryDetail;
import com.mjf.cjt.domain.TOtherInStockOrder;
import com.mjf.cjt.domain.TOtherInStockOrderDetails;
import com.mjf.cjt.mapper.TCjtzjbSaleDeliveryMapper;
import com.mjf.cjt.service.AsyncTMService;
import com.mjf.cjt.service.TCjtzjbSaleDeliveryDetailService;
import com.mjf.cjt.service.TCjtzjbSaleDeliveryService;
import com.mjf.cjt.vo.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
@Service
public class TCjtzjbSaleDeliveryServiceImpl extends ServiceImpl<TCjtzjbSaleDeliveryMapper, TCjtzjbSaleDelivery> implements TCjtzjbSaleDeliveryService {

    @Autowired
    private AsyncTMService asyncTMService;

    @Autowired
    private TCjtzjbSaleDeliveryDetailService tCjtzjbSaleDeliveryDetailService;


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void tCjtzjbSaleDelivery(String start, String end) {
        List<TCjtzjbSaleDelivery> list = list(Wrappers.<TCjtzjbSaleDelivery>lambdaQuery()
                .ge(StrUtil.isNotBlank( start), TCjtzjbSaleDelivery::getCreateTime, start)
                .le(StrUtil.isNotBlank( end), TCjtzjbSaleDelivery::getCreateTime, end)
                .eq(TCjtzjbSaleDelivery::getPushStatus, 0)
        );
        tCjtzjbSaleDelivery(list);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void tCjtzjbSaleDeliveryByIds(List<String> ids) {
        List<TCjtzjbSaleDelivery> list = list(Wrappers.<TCjtzjbSaleDelivery>lambdaQuery()
                .eq(TCjtzjbSaleDelivery::getPushStatus, 0)
                .in(TCjtzjbSaleDelivery::getId, ids));
        tCjtzjbSaleDelivery(list);
    }

    @Override
    public Page<TCjtzjbSaleDeliveryListVo> queryTCjtzjbSaleDelivery(TCjtzjbSaleDeliveryQueryParam param) {
        Page<TCjtzjbSaleDeliveryListVo> page = new Page<>(param.getPage(), param.getSize());
        page.setTotal(0);
        page.setRecords(new ArrayList<>());
        LambdaQueryWrapper<TCjtzjbSaleDelivery> qw = Wrappers.<TCjtzjbSaleDelivery>lambdaQuery()
                .ge(StrUtil.isNotBlank(param.getStart()), TCjtzjbSaleDelivery::getCreateTime, param.getStart())
                .le(StrUtil.isNotBlank(param.getEnd()), TCjtzjbSaleDelivery::getCreateTime, param.getEnd())
                .eq(TCjtzjbSaleDelivery::getPushStatus, param.getPushStatus())
                ;
        long count = count(qw);
        page.setTotal(count);
        qw.orderByDesc(TCjtzjbSaleDelivery::getCreateTime);
        qw.last("limit " + (param.getPage() - 1) * param.getSize() + "," + param.getSize());

        List<TCjtzjbSaleDelivery> list = list(qw);

        page.setRecords(list.stream().map(item -> TCjtzjbSaleDeliveryListVo.builder()
                        .id(item.getId())
                        .pushStatus(item.getPushStatus())
                        .result(item.getResult())
                        .times(item.getTimes())
                        .code(item.getCode())
                        .voucherDate(item.getVoucherDate())
                        .externalCode(item.getExternalCode())
                        .businessTypeCode(item.getBusinessTypeCode())
                        .invoiceTypeCode(item.getInvoiceTypeCode())
                        .customerCode(item.getCustomerCode())
                        .settleCustomerCode(item.getSettleCustomerCode())
                        .warehouseCode(item.getWarehouseCode())
                        .receiveWarehouseCode(item.getReceiveWarehouseCode())
                        .rdstyleCode(item.getRdstyleCode())
                        .isautoGenerateSaleout(item.getIsautoGenerateSaleout())
                        .deptCode(item.getDeptCode())
                        .clerkCode(item.getClerkCode())
                        .projectCode(item.getProjectCode())
                        .currencyCode(item.getCurrencyCode())
                        .exchangeRate(item.getExchangeRate())
                        .deliveryDate(item.getDeliveryDate())
                        .discountRate(item.getDiscountRate())
                        .origSettleAmount(item.getOrigSettleAmount())
                        .origAllowances(item.getOrigAllowances())
                        .ispriceTrace(item.getIspriceTrace())
                        .isautoGenerateInvoice(item.getIsautoGenerateInvoice())
                        .isseparateBywarehouse(item.getIsseparateBywarehouse())
                        .memberCode(item.getMemberCode())
                        .address(item.getAddress())
                        .sendDate(item.getSendDate())
                        .throughDate(item.getThroughDate())
                        .transNumber(item.getTransNumber())
                        .linkman(item.getLinkman())
                        .contactPhone(item.getContactPhone())
                        .customerPhone(item.getCustomerPhone())
                        .memo(item.getMemo())
                        .transDocno(item.getTransDocno())
                        .deliveryCode(item.getDeliveryCode())
                        .deliveryVoucherdate(item.getDeliveryVoucherdate())
                        .pubuserdefdecm1(item.getPubuserdefdecm1())
                        .pubuserdefdecm2(item.getPubuserdefdecm2())
                        .pubuserdefdecm3(item.getPubuserdefdecm3())
                        .pubuserdefdecm4(item.getPubuserdefdecm4())
                        .pubuserdefdecm5(item.getPubuserdefdecm5())
                        .pubuserdefnvc1(item.getPubuserdefnvc1())
                        .pubuserdefnvc2(item.getPubuserdefnvc2())
                        .pubuserdefnvc3(item.getPubuserdefnvc3())
                        .pubuserdefnvc4(item.getPubuserdefnvc4())
                        .pubuserdefnvc5(item.getPubuserdefnvc5())
                        .priuserdefdecm1(item.getPriuserdefdecm1())
                        .priuserdefdecm2(item.getPriuserdefdecm2())
                        .priuserdefdecm3(item.getPriuserdefdecm3())
                        .priuserdefdecm4(item.getPriuserdefdecm4())
                        .priuserdefdecm5(item.getPriuserdefdecm5())
                        .priuserdefnvc1(item.getPriuserdefnvc1())
                        .priuserdefnvc2(item.getPriuserdefnvc2())
                        .priuserdefnvc3(item.getPriuserdefnvc3())
                        .priuserdefnvc4(item.getPriuserdefnvc4())
                        .priuserdefnvc5(item.getPriuserdefnvc5())
                        .createTime(item.getCreateTime())
                        .updateTime(item.getUpdateTime())

                        .build())
                .collect(Collectors.toList()));
        return page;
    }

    public void tCjtzjbSaleDelivery(List<TCjtzjbSaleDelivery> list) {
        if (CollectionUtil.isEmpty(list)) {
            return;
        }

        // 查询销货单明细
        List<TCjtzjbSaleDeliveryDetail> detailList =
                tCjtzjbSaleDeliveryDetailService.list(Wrappers.<TCjtzjbSaleDeliveryDetail>lambdaQuery()
                        .in(TCjtzjbSaleDeliveryDetail::getMainId, list.stream()
                                .map(TCjtzjbSaleDelivery::getId).collect(Collectors.toList())));

        Map<Long, List<TCjtzjbSaleDeliveryDetail>> detailMap =
                detailList.stream().collect(Collectors.groupingBy(TCjtzjbSaleDeliveryDetail::getMainId));

        List<TCjtzjbSaleDelivery> updates = new ArrayList<>();
        for (TCjtzjbSaleDelivery item : list) {
            try {
                TCjtzjbSaleDeliveryCreateVo.Dto vo = TCjtzjbSaleDeliveryCreateVo.Dto.builder()
                        .Code(item.getExternalCode())
                        .IsModifiedCode(true)
                        .VoucherDate(String.valueOf(item.getVoucherDate()))
                        .ExternalCode(item.getExternalCode())
                        .BusinessType(TCjtzjbSaleDeliveryCreateVo.Dto.BusinessType.builder()
                                .Code(item.getBusinessTypeCode())
                                .build())
                        .InvoiceType(TCjtzjbSaleDeliveryCreateVo.Dto.InvoiceType.builder()
                                .Code(item.getInvoiceTypeCode())
                                .build())
                        .Customer(TCjtzjbSaleDeliveryCreateVo.Dto.Customer.builder()
                                .Code(item.getCustomerCode())
                                .build())
                        .SettleCustomer(TCjtzjbSaleDeliveryCreateVo.Dto.SettleCustomer.builder()
                                .Code(item.getSettleCustomerCode())
                                .build())
                        .Warehouse(TCjtzjbSaleDeliveryCreateVo.Dto.Warehouse.builder()
                                .Code(item.getWarehouseCode())
                                .build())
                        .ReceiveWarehouse(TCjtzjbSaleDeliveryCreateVo.Dto.ReceiveWarehouse.builder()
                                .Code(item.getReceiveWarehouseCode())
                                .build())
                        .RdStyle(TCjtzjbSaleDeliveryCreateVo.Dto.RdStyle.builder()
                                .Code(item.getRdstyleCode())
                                .IsAutoGenerateSaleOut(String.valueOf(item.getIsautoGenerateSaleout()))
                                .build())
                        .Department(TCjtzjbSaleDeliveryCreateVo.Dto.Department.builder()
                                .Code(item.getDeptCode())
                                .build())
                        .Clerk(TCjtzjbSaleDeliveryCreateVo.Dto.Clerk.builder()
                                .Code(item.getClerkCode())
                                .build())
                        .Project(TCjtzjbSaleDeliveryCreateVo.Dto.Project.builder()
                                .Code(item.getProjectCode())
                                .build())
                        .Currency(TCjtzjbSaleDeliveryCreateVo.Dto.Currency.builder()
                                .Code(item.getCurrencyCode())
                                .ExchangeRate(String.valueOf(item.getExchangeRate()))
                                .DeliveryDate(String.valueOf(item.getDeliveryDate()))
                                .build())
                        .ReciveType(TCjtzjbSaleDeliveryCreateVo.Dto.ReciveType.builder()
                                .DiscountRate(String.valueOf(item.getDiscountRate()))
                                .OrigSettleAmount(String.valueOf(item.getOrigSettleAmount()))
                                .OrigAllowances(String.valueOf(item.getOrigAllowances()))
                                .IsPriceTrace(String.valueOf(item.getIspriceTrace()))
                                .IsAutoGenerateInvoice(String.valueOf(item.getIsautoGenerateInvoice()))
                                .IsSeparateByWareHouse(String.valueOf(item.getIsseparateBywarehouse()))
                                .build())
                        .Member(TCjtzjbSaleDeliveryCreateVo.Dto.Member.builder()
                                .Code(item.getMemberCode())
                                .Address(item.getAddress())
                                .SendDate(String.valueOf(item.getSendDate()))
                                .ThroughDate(String.valueOf(item.getThroughDate()))
                                .TransNumber(item.getTransNumber())
                                .LinkMan(item.getLinkman())
                                .ContactPhone(item.getContactPhone())
                                .CustomerPhone(item.getCustomerPhone())
                                .Memo(item.getMemo())
                                .TransDocNo(item.getTransDocno())
                                .DeliveryCode(item.getDeliveryCode())
                                .DeliveryVoucherDate(String.valueOf(item.getDeliveryVoucherdate()))
                                .build())
                        .DynamicPropertyKeys(TCjtzjbSaleDeliveryCreateVo.Dto.DynamicPropertyKeys.builder()
                                .pubuserdefdecm1(String.valueOf(item.getPubuserdefdecm1()))
                                .pubuserdefdecm2(String.valueOf(item.getPubuserdefdecm2()))
                                .pubuserdefdecm3(String.valueOf(item.getPubuserdefdecm3()))
                                .pubuserdefdecm4(String.valueOf(item.getPubuserdefdecm4()))
                                .pubuserdefdecm5(String.valueOf(item.getPubuserdefdecm5()))
                                .pubuserdefnvc1(String.valueOf(item.getPubuserdefnvc1()))
                                .pubuserdefnvc2(String.valueOf(item.getPubuserdefnvc2()))
                                .pubuserdefnvc3(String.valueOf(item.getPubuserdefnvc3()))
                                .pubuserdefnvc4(String.valueOf(item.getPubuserdefnvc4()))
                                .pubuserdefnvc5(String.valueOf(item.getPubuserdefnvc5()))
                                .priuserdefdecm1(String.valueOf(item.getPriuserdefdecm1()))
                                .priuserdefdecm2(String.valueOf(item.getPriuserdefdecm2()))
                                .priuserdefdecm3(String.valueOf(item.getPriuserdefdecm3()))
                                .priuserdefdecm4(String.valueOf(item.getPriuserdefdecm4()))
                                .priuserdefdecm5(String.valueOf(item.getPriuserdefdecm5()))
                                .priuserdefnvc1(String.valueOf(item.getPriuserdefnvc1()))
                                .priuserdefnvc2(String.valueOf(item.getPriuserdefnvc2()))
                                .priuserdefnvc3(String.valueOf(item.getPriuserdefnvc3()))
                                .priuserdefnvc4(String.valueOf(item.getPriuserdefnvc4()))
                                .priuserdefnvc5(String.valueOf(item.getPriuserdefnvc5()))
                                .build())
                        .build();

                vo.setSaleDeliveryDetails(detailMap.get(item.getId()).stream().map(itemData ->
                    TCjtzjbSaleDeliveryCreateVo.Dto.SaleDeliveryDetails.builder()
                        .Warehouse(TCjtzjbSaleDeliveryCreateVo.Dto.SaleDeliveryDetails.Warehouse.builder()
                                .Code(itemData.getWarehouseCode())
                                .build())
                        .Project(TCjtzjbSaleDeliveryCreateVo.Dto.SaleDeliveryDetails.Project.builder()
                                .Code(itemData.getProjectCode())
                                .build())
                        .Inventory(TCjtzjbSaleDeliveryCreateVo.Dto.SaleDeliveryDetails.Inventory.builder()
                                .Code(itemData.getInventoryCode())
                                .InventoryBarCode(itemData.getInventoryBarcode())
                                .build())
                        .Unit(TCjtzjbSaleDeliveryCreateVo.Dto.SaleDeliveryDetails.Unit.builder()
                                .Name(itemData.getUnitName())
                                .build())
                        .Unit2(TCjtzjbSaleDeliveryCreateVo.Dto.SaleDeliveryDetails.Unit2.builder()
                                .Name2(itemData.getUnitName2())
                                .UnitExchangeRate(String.valueOf(itemData.getUnitExchangeRate()))
                                .Batch(itemData.getBatch())
                                .ExpiryDate(String.valueOf(itemData.getExpiryDate()))
                                .ProductionDate(String.valueOf(itemData.getProductionDate()))
                                .Quantity(String.valueOf(itemData.getQuantity()))
                                .OrigPrice(String.valueOf(itemData.getOrigPrice()))
                                .DiscountRate(String.valueOf(itemData.getDiscountRate()))
                                .OrigDiscountPrice(String.valueOf(itemData.getOrigDiscountPrice()))
                                .TaxRate(String.valueOf(itemData.getTaxRate()))
                                .OrigTaxAmount(String.valueOf(itemData.getOrigTaxAmount()))
                                .TaxAmount(String.valueOf(itemData.getTaxAmount()))
                                .build())
                        .RefundDifferenceFlag(TCjtzjbSaleDeliveryCreateVo.Dto.SaleDeliveryDetails.RefundDifferenceFlag.builder()
                                .IsPresent(String.valueOf(itemData.getIspresent()))
                                .DeliveryDate(String.valueOf(itemData.getDeliveryDate()))
                                .IsManualCost(String.valueOf(itemData.getIsmanualCost()))
                                .CostAmount(String.valueOf(itemData.getCostAmount()))
                                .CostPrice(String.valueOf(itemData.getCostPrice()))
                                .build())
                        .DynamicPropertyKeys(TCjtzjbSaleDeliveryCreateVo.Dto.SaleDeliveryDetails.DynamicPropertyKeys.builder()
                                .pubuserdefdecm1(String.valueOf(itemData.getPubuserdefdecm1()))
                                .pubuserdefdecm2(String.valueOf(itemData.getPubuserdefdecm2()))
                                .pubuserdefdecm3(String.valueOf(itemData.getPubuserdefdecm3()))
                                .pubuserdefdecm4(String.valueOf(itemData.getPubuserdefdecm4()))
                                .pubuserdefdecm5(String.valueOf(itemData.getPubuserdefdecm5()))
                                .pubuserdefnvc1(String.valueOf(itemData.getPubuserdefnvc1()))
                                .pubuserdefnvc2(String.valueOf(itemData.getPubuserdefnvc2()))
                                .pubuserdefnvc3(String.valueOf(itemData.getPubuserdefnvc3()))
                                .pubuserdefnvc4(String.valueOf(itemData.getPubuserdefnvc4()))
                                .pubuserdefnvc5(String.valueOf(itemData.getPubuserdefnvc5()))
                                .priuserdefdecm1(String.valueOf(itemData.getPriuserdefdecm1()))
                                .priuserdefdecm2(String.valueOf(itemData.getPriuserdefdecm2()))
                                .priuserdefdecm3(String.valueOf(itemData.getPriuserdefdecm3()))
                                .priuserdefdecm4(String.valueOf(itemData.getPriuserdefdecm4()))
                                .priuserdefdecm5(String.valueOf(itemData.getPriuserdefdecm5()))
                                .priuserdefnvc1(String.valueOf(itemData.getPriuserdefnvc1()))
                                .priuserdefnvc2(String.valueOf(itemData.getPriuserdefnvc2()))
                                .priuserdefnvc3(String.valueOf(itemData.getPriuserdefnvc3()))
                                .priuserdefnvc4(String.valueOf(itemData.getPriuserdefnvc4()))
                                .priuserdefnvc5(String.valueOf(itemData.getPriuserdefnvc5()))
                                .DetailMemo(String.valueOf(itemData.getDetailMemo()))
                                .build())
                            .build())
                        .collect(Collectors.toList())
                );

                TCjtzjbSaleDeliveryCreateVo vo1 = TCjtzjbSaleDeliveryCreateVo.builder()
                        .dto(vo)
                        .build();

                TFResultVO resultVO = asyncTMService.tCjtzjbSaleDelivery(vo1);
                item.setPushId(resultVO.getData().getId());
                item.setPushCode(resultVO.getData().getCode());
                item.setPushStatus(1);
                item.setPushResult(resultVO.getResult());
                item.setPushTime(LocalDateTime.now());
                updates.add(item);
            } catch (Exception e) {
                log.error("推送T+产成品入库单异常 {}, {}", e, item);
            }
        }
        if (CollectionUtil.isNotEmpty(updates)) {
            updateBatchById(updates);
        }
    }
}
